home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1985-12-03 | 4.4 KB | 174 lines |
- IMPLEMENTATION MODULE SymbolTable;
- (* Initializes symbol table. Maintains list of all labels, *)
- (* along with their values. Provides access to the list. *)
-
- FROM LongNumbers IMPORT
- LONG, LongClear;
-
- FROM Parser IMPORT
- TOKEN;
-
- FROM Strings IMPORT
- CompareStr;
-
-
- CONST
- MAXSYM = 500; (* Maximum entries in Symbol Table *)
-
-
- TYPE
- SYMBOL = RECORD
- Name : TOKEN;
- Value : LONG;
- END;
-
- VAR
- SymTab : ARRAY [1..MAXSYM] OF SYMBOL;
- Next : CARDINAL; (* Array index into next entry in Symbol Table *)
- Top : INTEGER; (* Last used array position as seen by Sort *)
-
-
-
- PROCEDURE FillSymTab (Label : TOKEN; Value : LONG; VAR Full : BOOLEAN);
- (* Add a symbol to the table *)
- BEGIN
- IF Next <= MAXSYM THEN
- SymTab[Next].Name := Label;
- SymTab[Next].Value := Value;
- INC (Next);
- Full := FALSE;
- ELSE
- Full := TRUE;
- END;
- END FillSymTab;
-
-
-
- PROCEDURE SortSymTab (VAR NumSyms : CARDINAL);
- (* Sort symbols into alphabetical order *)
-
- VAR
- i, j, gap : INTEGER; (* Shell Sort causes j to go negative *)
- Temp : SYMBOL;
-
- PROCEDURE Swap;
- BEGIN
- Temp := SymTab[j];
- SymTab[j] := SymTab[j + gap];
- SymTab[j + gap] := Temp;
- END Swap;
-
- BEGIN (* Sort *)
- Top := Next - 1;
-
- gap := (Top + 1) DIV 2;
- WHILE gap > 0 DO
- i := gap;
- WHILE i <= Top DO
- j := i - gap;
- WHILE j >= 1 DO
- IF CompareStr (SymTab[j].Name, SymTab[j + gap].Name) > 0 THEN
- Swap;
- END;
- j := j - gap;
- END;
- INC (i);
- END;
- gap := gap DIV 2;
- END;
-
- NumSyms := Top;
- END SortSymTab;
-
-
-
- PROCEDURE ReadSymTab (LABEL : ARRAY OF CHAR;
- VAR Value : LONG; VAR Duplicate : BOOLEAN) : BOOLEAN;
- (* Passes Value of Label to calling program -- returns FALSE if the *)
- (* Label is not defined. Also checks for Multiply Defined Symbols *)
-
- CONST
- GoLower = -1;
- GoHigher = +1;
-
- VAR
- i, j, mid : INTEGER;
- Search : INTEGER;
- Found : BOOLEAN;
- c : CHAR;
- Label : TOKEN;
-
- BEGIN
- LongClear (Value);
- Duplicate := FALSE;
-
- i := 0;
- REPEAT
- c := LABEL[i];
- Label[i] := c;
- INC (i);
- UNTIL (c = 0C) OR (i > 8);
-
- IF c # 0C THEN (* Operand label too long --> Undefined *)
- RETURN FALSE;
- END;
-
- i := 1;
- j := Top;
- Found := FALSE;
-
- REPEAT (* Binary search *)
- mid := (i + j) DIV 2;
- Search := CompareStr (Label, SymTab[mid].Name);
-
- IF Search = GoLower THEN
- j := mid - 1;
- ELSIF Search = GoHigher THEN
- i := mid + 1;
- ELSE (* Got It! *)
- Found := TRUE;
- END;
- UNTIL (j < i) OR Found;
-
- IF Found THEN
- IF mid > 1 THEN
- IF CompareStr (SymTab[mid].Name, SymTab[mid - 1].Name) = 0 THEN
- Duplicate := TRUE; (* Multiply Defined Symbol *)
- END;
- END;
- IF mid < Top THEN
- IF CompareStr (SymTab[mid].Name, SymTab[mid + 1].Name) = 0 THEN
- Duplicate := TRUE; (* Multiply Defined Symbol *)
- END;
- END;
-
- Value := SymTab[mid].Value;
- RETURN TRUE;
- ELSE
- RETURN FALSE;
- END;
- END ReadSymTab;
-
-
-
- PROCEDURE ListSymTab (i : CARDINAL; VAR Label : TOKEN; VAR Value : LONG);
- (* Returns the i-th item in the symbol table *)
- BEGIN
- IF i < Next THEN
- Label := SymTab[i].Name;
- Value := SymTab[i].Value;
- END;
- END ListSymTab;
-
-
-
- BEGIN (* MODULE Initialization *)
- FOR Next := 1 TO MAXSYM DO
- SymTab[Next].Name := "";
- LongClear (SymTab[Next].Value);
- END;
-
- Top := 0;
- Next := 1;
- END SymbolTable.